<template>
    <!-- 录音题 - 题目 -->
  <div>
      <p class="font-size16 margin-bottom10">[{{ $t("SR") }}]</p><!--录音题-->
      <div class="font-size16" style="margin-bottom: 30px;" v-if="currentSubIndex!==null">
          ({{currentSubIndex + 1}}). <span v-html="$xss(imgHandle(queTitle))"></span>
      </div>
      <div class="font-size16" style="margin-bottom: 30px;" v-else>
          {{currentIndex + 1}}. <span v-html="$xss(imgHandle(queTitle))"></span>
      </div>
      <div :class="`ctrlProcessWave-`+info.id" style="height:100px;width:80%;margin:0 auto;box-sizing: border-box;margin-bottom: 20px;vertical-align:bottom"></div>
      <div class="btn-area">
        <div class="play-box playing">
            <span v-if="srUrl && !recording" class="" @click="playRecorder()">{{$t('exam-play')}}</span>
            <span v-if="srUrl && recording" class="" @click="pausePlayRecorder()">{{$t('pause')}}</span>
        </div>
        <span class="startRecord"  @click="openRecorder()" v-if="!startRecording">{{$t('exam-recording')}}</span>
        <span class="startRecord" @click="stopRecorder()" v-else>{{$t('exam-stop')}}</span>
        <div  class="play-box">
            <span v-if="srUrl && !completeUpdate && completeRecord" @click="uploadSr()">{{$t('exam-upload')}}</span>
            <span v-if="srUrl && completeUpdate" >{{$t('exam-uploaded')}}</span>
        </div>
      </div>
      <div style="margin-top:20px;display:none">
        <audio :src="srUrl"  controls="controls" :ref="`audioPlayer-`+info.id"></audio>
      </div>
  </div>
</template>

<script>

import Recorder from 'recorder-core/recorder.mp3.min';
//可选的插件支持项
import 'recorder-core/src/extensions/waveview'; // 波形扩展
//BufferStreamPlayer插件：实时播放录音片段文件，把片段文件转换成MediaStream流
import 'recorder-core/src/extensions/buffer_stream.player';
import { Notify } from 'vant';
export default {
    name: 'exam-sr',
    components: {
        [Notify.Component.name]: Notify.Component
    },
    props: {
        info: { // 题目信息
            type: Object,
            default() {
                return {};
            }
        },
        currentIndex: { // 当前题目索引
            type: Number,
            default() {
                return 1;
            }
        },
        currentSubIndex: { // 传了就代表是情景题内的索引
            type: Number,
            default() {
                return null;
            }
        },
        saveUrl: { // 保存信息
            type: String,
            default() {
                return '';
            }
        },
        questionType: { // 题目类型
            type: String,
            default() {
                return 'only';
            }
        },
        examId: { // 测验id
            type: String
        },
        thkId: { // 报名id
            type: String
        },
        outChangeLabel: { // 是否标记
            type: Boolean,
            default() {
                return false;
            }
        }
    },
    data() {
        return {
            queTitle: '',
            rec: null,
            listener: null, // 播放对象
            blobData: null,
            isOpenRec: false, // 是否已经初始化完成录音软件。
            completeUpdate: false,
            completeRecord: false,
            isMark: false,
            letterList: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
            isDoing: false, // 正在答题
            // 波浪图-录音
            drawRecordId: null,
            oCanvas: null,
            ctx: null,
            // 波浪图-播放
            drawPlayId: null,
            pCanvas: null,
            pCtx: null,
            srUrl: '', // 上传录音回调地址
            recording: false, // 是否在回放录音
            startRecording: false, // 是否正在录音
            wave: null, // 声波波浪
            recorder: null,
            stream: null // 录音文件mp3解析
        };
    },
    methods: {
        imgHandle(txt) {
            let parser = new DOMParser();
            let dom = parser.parseFromString(txt, 'text/html');
            // 处理auido标签
            let audioTags = dom.querySelectorAll('audio');
            audioTags.forEach(audioTag => {
                let src = audioTag.getAttribute('src');
                if (src) {
                    audioTag.setAttribute('src', this.appUrl + src);
                }
            });
            // 处理 <video> 标签
            let videoTags = dom.querySelectorAll('video');
            videoTags.forEach(videoTag => {
                let src = videoTag.getAttribute('src');
                if (src) {
                    videoTag.setAttribute('src', this.appUrl + src);
                }
            });
            // 处理 <img> 标签
            let imgTags = dom.querySelectorAll('img');
            imgTags.forEach(imgTag => {
                let src = imgTag.getAttribute('src');
                if (src) {
                    imgTag.setAttribute('src', this.appUrl + src);
                }
            });
            let htmlContent = dom.documentElement.innerHTML;
            htmlContent = htmlContent.replace(/<head>[.\s\S]*?<\/head>/, '').replace(/<body>|<\/body>/g, '');

            return htmlContent;
        },
        onChange(item) {
            if (!this.isDoing) {
                this.isDoing = true;
                this.$emit('on-change', this.info.id);
            }
            const obj = {
                quesId: this.info.id,
                type: this.info.type,
                answer: {
                    queId: this.info.id,
                    answerShort: this.textarea
                }
            };
            this.isDoing = false;
            this.$emit('on-select', obj);
        },
        onLabel() {
            this.isMark = !this.isMark;
            const obj = {
                mark: this.isMark,
                item: this.info.id,
                index: this.currentIndex
            };
            this.$emit('on-label', obj);
        },
        handleData() {
            if (this.saveUrl) {
                this.srUrl = this.appUrl + JSON.parse(JSON.stringify(this.saveUrl));
            }
            this.quesInfo = {...this.info};
            // 富文本字符串检查是否存在audio，是则src添加appUrl
            let parser = new DOMParser();
            let dom = parser.parseFromString(this.quesInfo.subject, 'text/html');
            let audioTags = dom.querySelectorAll('audio');
            audioTags.forEach(audioTag => {
                let src = audioTag.getAttribute('src');
                if (src) {
                    audioTag.setAttribute('src', this.appUrl + src);
                }
            });

            this.queTitle = dom.documentElement.innerHTML;
        },
        formatMs(ms, all) {
            var ss = ms % 1000; ms = (ms - ss) / 1000;
            var s = ms % 60; ms = (ms - s) / 60;
            var m = ms % 60; ms = (ms - m) / 60;
            var h = ms;
            var t = (h ? h + ':' : '') +
                (all || h + m ? ('0' + m).substr(-2) + ':' : '') +
                (all || h + m + s ? ('0' + s).substr(-2) + '″' : '') +
            ('00' + ss).substr(-3);
            return t;
        },
        /**
         *  录音的具体操作功能
         * */
        // 开始录音
        openRecorder() {
            if (process.env.NODE_ENV === 'production_app') {
                // 获取安卓录音权限弹窗
                // 判断是否安卓
                if (/(android)/i.test(navigator.userAgent)) {
                    window.plus.android.requestPermissions(['android.permission.RECORD_AUDIO'], (e) => {
                        if (e.deniedAlways.length > 0) { //权限被永久拒绝
                            Notify({
                                type: 'warning',
                                message: this.$t('Recording_permission')
                            });
                            return false;
                        }
                        if (e.deniedPresent.length > 0) { //权限被临时拒绝
                            Notify({
                                type: 'warning',
                                message: this.$t('Recording_permission')
                            });
                            return false;
                        }
                        if (e.granted.length > 0) { //权限被允许
                            this.openRecorderFunc();
                        }
                    }, function(e) {
                        console.log('Request Permissions error:' + JSON.stringify(e));
                    });
                } else {
                    this.openRecorderFunc();
                }
            } else {
                this.openRecorderFunc();
            }
        },
        openRecorderFunc() {
            if (!this.recorder) {
                this.recorder = Recorder({
                    type: 'mp3', //录音格式，可以换成wav等其他格式
                    sampleRate: 48000, //录音的采样率，越大细节越丰富越细腻
                    bitRate: 16, //录音的比特率，越大音质越好
                    onProcess: (buffers, powerLevel, duration, sampleRate) => {
                        //录音实时回调，大约1秒调用12次本回调
                        //可实时绘制波形，实时上传（发送）数据
                        this.duration = duration;
                        this.durationTxt = this.formatMs(duration, 1);
                        this.powerLevel = powerLevel;
                        this.wave.input(buffers[buffers.length - 1], powerLevel, sampleRate);
                    }
                });
                this.recorder.open(() => {
                    if (!this.wave) {
                        this.wave = Recorder.WaveView({elem: '.ctrlProcessWave-' + this.info.id});
                    }

                    this.isOpenRec = true;
                    this.startRecorder();
                }, function(msg, isUserNotAllow) {
                });
            } else {
                this.startRecorder();
            }
        },
        startRecorder() {
            if (!this.recorder || !Recorder.IsOpen()) {
                // 未打开录音
                return;
            }
            this.recorder.start();
            this.recording = false;
            this.startRecording = true;
            this.completeUpdate = false;
            if (this.completeRecord) {
                this.completeRecord = false;
            }
        },
        // 结束录音
        stopRecorder() {
            if (!this.recorder || !Recorder.IsOpen()) {
                // 未打开录音
                return;
            }
            this.startRecording = false;
            this.completeRecord = true;
            this.recorder.stop((blob, duration) => {
                this.blobData = blob;
                this.srUrl = window.URL.createObjectURL(blob);
                this.destroyRecorder();
            });
        },
        destroyRecorder() {
            if (this.recorder) {
                this.recorder.close();
                this.recorder = null;
            }
        },
        // 录音播放
        playRecorder() {
            this.recording = true;
            if (this.blobData || this.srUrl) {
                this.player = this.$refs['audioPlayer-' + this.info.id];
                // 当音频播放时实时生成波形图像
                if (!this.wave) {
                    this.wave = Recorder.WaveView({elem: '.ctrlProcessWave-' + this.info.id});
                }
                this.player.onplay = () => {
                    if (this.rec) {
                        this.rec.resume();
                        return;
                    };
                    //必须等待到可以开始播放后（onloadedmetadata），流内才会有音轨，在onplay内很安全
                    this.recStart(this.player.captureStream());
                };
                this.player.onpause = () => {
                    if (this.rec) {
                        this.rec.pause();
                    };
                };
                this.player.onended = () => {
                    this.player && this.player.pause();
                    this.recording = false;
                    var rec2 = this.rec;
                    this.rec = 0;
                    if (!rec2) {
                        return;
                    };

                    rec2.stop((blob, duration) => {
                        rec2.close();//释放录音资源
                    }, function(msg) {
                    });
                };
                this.player.play();
            } else { // 没有录音数据可播放
            }
        },
        // 播放录音时的波纹显示
        recStart(stream) {
            if (this.rec) { //清理掉已有的
                this.rec.close();
                this.rec = null;
            };

            this.rec = Recorder({
                type: 'mp3',
                sampleRate: 48000,
                bitRate: 16,
                sourceStream: stream, //明确指定从这个流中录制音频
                onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate) => {
                    this.wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate);
                }
            });

            this.rec.open(() => { //打开这个流
                this.rec.start();//开始录制
            }, (msg) => {
                console.log('error');
            });
        },
        // 暂停录音播放
        pausePlayRecorder() {
            this.recording = false;
            let audio = this.$refs['audioPlayer-' + this.info.id];
            if (!(audio.ended || audio.paused)) {
                audio.pause();
            };
        },
        /**
         * @description: 上传录音文件MP3
         * @param {*}
         * @return {*}
         */
        uploadSr() {
            const fileData = new FormData();
            fileData.append('file', this.blobData, this.info.id + '.mp3');
            this.$axios({
                method: 'POST',
                url: `/app/api/file/recording/${this.examId}/${this.thkId}`,
                data: fileData
            }).then(res => {
                if (res) {
                    this.srUrl = res.data;
                    this.completeUpdate = true;
                    if (!this.isDoing) {
                        this.isDoing = true;
                        this.$emit('on-change', this.info.id);
                    }
                    const obj = {
                        quesId: this.info.id,
                        type: this.info.type,
                        answer: {
                            queId: this.info.id,
                            answerShort: this.srUrl
                        }
                    };
                    this.isDoing = false;
                    if (this.currentSubIndex !== null) {
                        this.$emit('on-select', 'SR', obj, this.info.id, this.currentIndex, this.currentSubIndex);
                    } else {
                        this.$emit('on-select', 'SR', obj, this.info.id, this.currentIndex);
                    }
                }
            });
        }
    },
    mounted() {
        this.handleData();
    },
    watch: {
        'info'() {
            this.handleData();
        },
        'saveUrl'(old, newValue) {
            this.handleData();
        },
        outChangeLabel(val) {
            // console.log(val)
            this.isMark = val;
        }
    }
};
</script>

<style lang="less" scoped>
.btn-area{
    display: flex;
    justify-content: center;
    align-items: center;
}
.startRecord{
  height:80px;
  width: 80px;
  border-radius: 50%;
  display: block;
  line-height: 80px;
  background: #075ebb;
  color: #fff;
  text-align: center;
  margin: 0 30px;
}
.play-box{
    width: 80px;
    &.playing{
        >span{
            display: block;
            text-align: right;
        }
    }
}
</style>
